#ifndef ACCESSCONTROLENTRY_H
#define ACCESSCONTROLENTRY_H

#include <sys/types.h>
#include <string>

#include "common_includes.h"
#include "ftp_user.h"
#include "ftp_group.h"

AUTH_NS_START

enum AccessRightFlags {
	NONE_ACCESS = 0x0,
	READ_ACCESS = 0x01,
	WRITE_ACCESS = 0x02,
	EXECUTE_ACCESS = 0x04,
	INVALID_ACCESS_RIGHT_VALUE = 0x09	// Acts as the End Block. Use it in Each check by & ~(INVALID_ACCESS_RIGHT_VALUE-1)
};

/**
 * @class AccessControlEntry
 * @brief Access Control Entry
 */
class AccessControlEntry {

private:
	/**
	 * @brief Prevent copy construction
	 * @param rhs
	 */
	AccessControlEntry(const AccessControlEntry& rhs);

	/**
	 * @brief Prevent shallow copy
	 * @param rhs
	 */
	AccessControlEntry& operator=(const AccessControlEntry& rhs);

	bool m_bIsPositive;

	AccessRightFlags m_nAccessRights;

	bool m_bIsRightForGroup;

	uid_t m_nUserSid;

	gid_t m_nGroupSid;

	std::string m_nFilename;

public:

	/**
	 * @brief Creates an Access Control Entry for a FTP User
	 * @param filename The Target filename
	 * @param user The user for which this ACE is created
	 * @param accessRights The Access rights for the user.
	 * @param isPositiveRight Whether the right is an ALLOW or DENY
	 */
	AccessControlEntry(std::string& filename, const FtpUser* user, AccessRightFlags accessRights, bool isPositiveRight = false);

	/**
	 * @brief Creates an ACE for a FTP group
	 * @param filename The Target Filename
	 * @param grp The group for which this ACE is created
	 * @param accessRights The Access rights for the user
	 * @param isPositiveRight Whether the right is an ALLOW or DENY
	 */
	AccessControlEntry(std::string& filename, const FtpGroup* grp, AccessRightFlags accessRights, bool isPositiveRight = false);

	virtual ~AccessControlEntry();

	/**
	 * @brief Gets whether the ACE is Positive
	 * @return true if ACE is positive, false if negative
	 */
	bool  GetIsPositive() const {
		return m_bIsPositive;
	}

	/**
	 * @brief Gets whether this ACE is for a Group
	 * @return true if ACE is for group, false if it for a user.
	 */
	bool  GetIsRightForGroup() const {
		return m_bIsRightForGroup;
	}

	/**
	 * @brief Gets the Access Rights Flags associated with this ACE
	 * @return AccessRightsFlags instance
	 */
	const AccessRightFlags & GetAccessRights() const {
		return m_nAccessRights;
	}

	/**
	 * @brief Gets the Group SID. This makes sense only if this ACE is for a group
	 * @return The Group SID
	 */
	const gid_t & GetGroupSid() const {
		return m_nGroupSid;
	}

	/**
	 * @brief Gets the User SID. This makes sense only if this ACE is for a user
	 * @return The User SID
	 */
	const uid_t & GetUserSid() const {
		return m_nUserSid;
	}

	/**
	 * @brief Gets the Filename to which the ACE applies
	 * @return The Filename
	 */ 
	const std::string & GetFilename() const {
		return m_nFilename;
	}
};

AUTH_NS_END

#endif // ACCESSCONTROLENTRY_H
